inline
Semaphore::Semaphore (int init_num/* = 0*/)
{
#if defined NDK_LINUX
    ::sem_init (&sem_, 0, init_num);
#elif defined NDK_WIN32
    sem_ = CreateSemaphore (0, init_num, LONG_MAX, 0);
#endif
}
inline
Semaphore::~Semaphore ()
{
#if defined NDK_LINUX
    size_t retry = 0;
    while ((::sem_destroy (&sem_) == -1) && retry < 3)
    {
	if (errno == EBUSY)
	{
	    retry ++;
	    this->post ();
	    Thread::yield ();
	}else 
	    break;
    }
#elif defined NDK_WIN32
    CloseHandle (this->sem_);
#endif
}
inline
int Semaphore::wait ()
{
#if defined NDK_LINUX
    int ret = -1;
    do{
	ret = ::sem_wait (&sem_);
    }while (ret == -1 && errno == EINTR);
    return ret; 
#elif defined NDK_WIN32
    return this->wait (0);
#endif
}
#if 0
    struct timespec timeout;
    struct timeval  tp;
    ::gettimeofday (&tp, 0);
    timeout.tv_sec   = (msec / 1000) + tp.tv_sec;
    timeout.tv_nsec  = ((msec % 1000) * 1000000) + (tp.tv_usec * 1000);
    while (timeout.tv_nsec >= 1000000000)
    {
	timeout.tv_nsec -= 1000000000;
	timeout.tv_sec++;
    }
#endif
inline
int Semaphore::wait (const TimeValue *timeout)
{
#if defined NDK_LINUX
    if (timeout == 0)
        return this->wait ();
    struct timespec ts;
    ts = NDK::gettimeofday () + *timeout;
    int ret = -1;
    do{
        ret = ::sem_timedwait (&this->sem_, &ts);
    }while (ret == -1 && errno == EINTR);
    return ret;
#elif defined NDK_WIN32
    DWORD wait_time = 0;
    if (timeout == 0)
        wait_time = INFINITE;
    else
        wait_time = timeout->msec ();
    int result = WaitForSingleObject (this->sem_, wait_time);
    if (result != WAIT_OBJECT_0)
        result = -1;
    return result;
#endif
}
inline
int Semaphore::trywait ()
{
#if defined NDK_LINUX
    return ::sem_trywait (&this->sem_);
#elif defined NDK_WIN32
    return this->wait (&TimeValue::zero ());
#endif
}
inline
int Semaphore::post ()
{
#if defined NDK_LINUX
    return ::sem_post (&this->sem_);
#elif defined NDK_WIN32
    return ReleaseSemaphore (this->sem_, 1, NULL) ? 0 : -1;
#endif
}
inline
int Semaphore::post (int post_count)
{
#if defined NDK_LINUX
    int ret = 0;
    int n = post_count;
    while (n-- > 0)
        if (::sem_post (&sem_) == 0) ret++;
    return post_count != ret ? -1 : ret;
#elif defined NDK_WIN32
    return ReleaseSemaphore (this->sem_, post_count, NULL) ? 0 : -1;
#endif
}

